#define l3_disallow_mask(d) L3_DISALLOW_MASK
#endif
-static void queue_deferred_ops(struct domain *d, unsigned int ops)
-{
- ASSERT(d == current->domain);
- this_cpu(percpu_mm_info).deferred_ops |= ops;
-}
-
void __init init_frametable(void)
{
unsigned long nr_pages, page_step, i, mfn;
}
-static void invalidate_shadow_ldt(struct vcpu *v)
+static void invalidate_shadow_ldt(struct vcpu *v, int flush)
{
int i;
unsigned long pfn;
struct page_info *page;
+ BUG_ON(unlikely(in_irq()));
+
+ spin_lock(&v->arch.shadow_ldt_lock);
+
if ( v->arch.shadow_ldt_mapcnt == 0 )
- return;
+ goto out;
v->arch.shadow_ldt_mapcnt = 0;
put_page_and_type(page);
}
- /* Dispose of the (now possibly invalid) mappings from the TLB. */
- if ( v == current )
- queue_deferred_ops(v->domain, DOP_FLUSH_TLB | DOP_RELOAD_LDT);
- else
- flush_tlb_mask(v->domain->domain_dirty_cpumask);
+ /* Rid TLBs of stale mappings (guest mappings and shadow mappings). */
+ if ( flush )
+ flush_tlb_mask(v->vcpu_dirty_cpumask);
+
+ out:
+ spin_unlock(&v->arch.shadow_ldt_lock);
}
nl1e = l1e_from_pfn(mfn, l1e_get_flags(l1e) | _PAGE_RW);
+ spin_lock(&v->arch.shadow_ldt_lock);
l1e_write(&v->arch.perdomain_ptes[off + 16], nl1e);
v->arch.shadow_ldt_mapcnt++;
+ spin_unlock(&v->arch.shadow_ldt_lock);
return 1;
}
(d == e) )
{
for_each_vcpu ( d, v )
- invalidate_shadow_ldt(v);
+ invalidate_shadow_ldt(v, 1);
}
put_page(page);
}
return 0;
}
- invalidate_shadow_ldt(curr);
+ invalidate_shadow_ldt(curr, 0);
write_ptbase(curr);
return 1;
return 0;
}
- invalidate_shadow_ldt(curr);
+ invalidate_shadow_ldt(curr, 0);
old_base_mfn = pagetable_get_pfn(curr->arch.guest_table);
flush_tlb_local();
}
+ /*
+ * Do this after flushing TLBs, to ensure we see fresh LDT mappings
+ * via the linear pagetable mapping.
+ */
if ( deferred_ops & DOP_RELOAD_LDT )
(void)map_ldt_shadow_page(0);
else if ( (curr->arch.guest_context.ldt_ents != ents) ||
(curr->arch.guest_context.ldt_base != ptr) )
{
- invalidate_shadow_ldt(curr);
+ invalidate_shadow_ldt(curr, 0);
+ this_cpu(percpu_mm_info).deferred_ops |= DOP_FLUSH_TLB;
curr->arch.guest_context.ldt_base = ptr;
curr->arch.guest_context.ldt_ents = ents;
load_LDT(curr);